/*
    YmsgIRC - Program enabling YMSG chat clients to use IRC
    Copyright (C) 2011 Crash Daemonicus ( crashenator -at- gmail.com )

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "YMSG_list.h"

YmsgItem::YmsgItem(){type=0;}

YmsgItem::YmsgItem(int itype,YmsgField& field){type=itype;fields.push_back(field);}
YmsgItem::YmsgItem(int itype,vector<YmsgField> fields2){type=itype;fields=fields2;}

void YmsgItem::setValue(int num, const string& value)
{
	vector<YmsgField>::iterator it=findModifiable(num);
	if(it==fields.end()) return;
	it->value = value;
	it->assemble();
}

void YmsgItem::addField(int num, const string& value)
{
	fields.push_back(YmsgField(num,value));
}


vector<YmsgField> YmsgItem::toFields() const
{
	string sType=itos(type);
	vector<YmsgField> fields2=fields;
	if(type!=0){
		fields2.insert(fields2.begin(),YmsgField(YMSG_FIELD_ITEMBEGIN,sType));
		fields2.push_back(YmsgField(YMSG_FIELD_ITEMEND,sType));
	}
	return fields2;
}

string YmsgItem::toString(){
	string contents="";
	vector<YmsgField> fields2=toFields();
	foreach_vector(YmsgField,it,fields) contents+=(*it).toString();
	return contents;
}

vector<YmsgField>::const_iterator  YmsgItem::find(const int& type,const string& data) const
{
	return std::find(fields.begin(),fields.end(),YmsgField(type,data));
}
vector<YmsgField>::const_iterator  YmsgItem::find(const YmsgField& field) const
{
	return std::find(fields.begin(),fields.end(),field);
}


vector<YmsgField>::const_iterator  YmsgItem::find(int type,int occur) const
{
	int found=0;
	foreach_vector_const(YmsgField,it,fields)
	{
		if((*it).num==type)
		{
			found++;
			if(found==occur) return it;
		}
	}
	return fields.end();
}
vector<YmsgField>::iterator YmsgItem::findModifiable(int type,int occur)
{
	int found=0;
	foreach_vector(YmsgField,it,fields)
	{
		if((*it).num==type)
		{
			found++;
			if(found==occur) return it;
		}
	}
	return fields.end();
}




string YmsgItem::getValue(int type, int occur) const
{
	vector<YmsgField>::const_iterator it=find(type,occur);
	if(it==fields.end()) return "";
	return (*it).value;
}




const YmsgItem& YmsgItem::operator=(vector<YmsgField> fields2){fields=fields2; return *this; }
const YmsgItem& YmsgItem::operator+=(const YmsgField& field){ fields.push_back(field); return *this; }
vector<YmsgItem> YmsgItem::operator+(const YmsgItem& item2)
{
	vector<YmsgItem> items;
	items.push_back(*this);
	items.push_back(item2);

	return items;
}

vector<YmsgField> YmsgItem::operator+(vector<YmsgField> fields2)
{
	vector<YmsgField> tmpFields=toFields();
	tmpFields.insert(tmpFields.end(),fields2.begin(),fields2.end());
	return tmpFields;
}

void YmsgItem::debug() const
{
	dbg_head("YmsgItem");
	dbgline(itos(type).c_str());
	dbg_vec(fields);
	dbg_foot(0);
}

//------------------------------------------------------


YmsgList::YmsgList(){type=0;}
YmsgList::YmsgList(int itype){type=itype;}
YmsgList::YmsgList(int itype,YmsgItem& item){type=itype;items.push_back(item);}
YmsgList::YmsgList(int itype,vector<YmsgItem> items2){type=itype;items=items2;}


void YmsgList::addItem(const vector<YmsgField>& fields){ items.push_back(YmsgItem(type,fields)); }
void YmsgList::addItem(const YmsgItem& item){ items.push_back(item); }

vector<YmsgField> YmsgList::toFields() const
{
	string sType=itos(type);
	vector<YmsgField> fields;
	foreach_vector_const(YmsgItem,it,items)
	{
		vector<YmsgField> fields2=(*it).toFields();
		fields.insert(fields.end(),fields2.begin(),fields2.end());
	}
	if(type!=0){
		fields.insert(fields.begin(),YmsgField(YMSG_FIELD_LISTBEGIN,sType));
		fields.push_back(YmsgField(YMSG_FIELD_LISTEND,sType));
	}
	return fields;
}

YmsgItem YmsgList::toItem(){  return YmsgItem(0,toFields());  }

string YmsgList::toString(){//*** check this to make sure all containers are visible.
	string contents="";
	string sType=itos(type);
	if(type!=0) contents =YmsgField(YMSG_FIELD_LISTBEGIN,sType).toString();
	foreach_vector(YmsgItem,it,items) contents+=(*it).toString();
	if(type!=0) contents+=YmsgField(YMSG_FIELD_LISTEND  ,sType).toString();
	return contents;
}

vector<YmsgList>  YmsgList::operator+(const YmsgList& list){
	vector<YmsgList> lists;
	lists.push_back(*this);
	lists.push_back(list);
	return lists;
}
vector<YmsgField> YmsgList::operator+(const YmsgField& field){
	vector<YmsgField> fields=toFields();
	fields.push_back(field);
	return fields;
}

vector<YmsgField> YmsgList::operator+(vector<YmsgField> fields2){
	vector<YmsgField> fields=toFields();
	fields.insert(fields.end(),fields2.begin(),fields2.end());
	return fields;
}

void YmsgList::debug() const
{
	dbg_head("YmsgList");
	dbgline(itos(type).c_str());
	dbg_vec(items);
	dbg_foot(0);
}
